package com.glp.common.shiro.config;

import com.glp.common.shiro.realm.UserRealm;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @author xyl
 * @create 2020/7/23 9:12
 * @desc 最主要的就是 1. UserRealm   2.DefaultWebSecurityManager  3.ShiroFilterFactoryBean
**/
@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        factoryBean.setSecurityManager(defaultWebSecurityManager);
        /**
         * anon :无需认证
         * authc : 必须认证了才能访问
         * user : 必须用于 记住我 才能用
         * perms : 拥有对某个资源的权限才能访问;
         * role : 拥有某个角色才能访问
         */
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/login","anon");
        filterMap.put("/device-record/qrcode","anon");    //扫二维码弹出的页面
        filterMap.put("/upload/*","anon");
//        filterMap.put("/entrust/submit-view","perms[entrust:submit-view]");
        filterMap.put("/index","authc");
        filterMap.put("/report/client/*","authc");
        filterMap.put("/report/admin/*","authc");
        filterMap.put("/report/*","authc");
        filterMap.put("/user/*","authc");
        filterMap.put("/admin/*","authc");
        factoryBean.setFilterChainDefinitionMap(filterMap);
        //若没authc权限 , 设置默认登录的页面
        factoryBean.setLoginUrl("/login");
        //若没授权  , 设置默认授权页面
        factoryBean.setUnauthorizedUrl("/login");
        return factoryBean;
    }

    //DefaultWebSecurityManager
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联Realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //创建realm 对象
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }



    @Bean(name = "sessionManager")
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 设置session过期时间3600s * 100
        sessionManager.setGlobalSessionTimeout(36000000L);
        return sessionManager;
    }

    /**
     * 开启shiro注解时 权限认证
     * @return
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    /**
     * 未授权页面跳转
     * @return
     */
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        /*未授权处理页*/
        properties.setProperty("org.apache.shiro.authz.UnauthorizedException", "/login");
        /*身份没有验证*/
        properties.setProperty("org.apache.shiro.authz.UnauthenticatedException", "/login");
        resolver.setExceptionMappings(properties);
        return resolver;
    }
}